﻿using Abp.Domain.Repositories;
using MyCompanyName.AbpZeroTemplate.Prm.Document.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Project;
using MyCompanyName.AbpZeroTemplate.Prm.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Abp.AutoMapper;
using System.Threading.Tasks;
using System.IO;
using System.Web;

namespace MyCompanyName.AbpZeroTemplate.Prm.Document
{
    public class DocumentAppService : AbpZeroTemplateAppServiceBase, IDocumentAppService
    {
        private readonly ProjectManager projectManager;
        private readonly OperationLogManager operationLogManager;
        private readonly IRepository<DocumentType> documentTypeRepository;

        public DocumentAppService(ProjectManager _projectManager, IRepository<DocumentType> _documentTypeRepository, OperationLogManager _operationLogManager)
        {
            projectManager = _projectManager;
            operationLogManager = _operationLogManager;
            documentTypeRepository = _documentTypeRepository;
        }



        /// <summary>
        /// 文档类型树
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetDocumentCheckedTreeDto>> GetDocumentTree(int projectId)
        {
            var types = await documentTypeRepository.GetAllListAsync();

            var pdocs = projectManager.projectDocTypeRepository.GetAll().Where(x => x.ProjectId == projectId).Select(x => x.DocTypeId).ToList();

            List<GetDocumentCheckedTreeDto> result = new List<GetDocumentCheckedTreeDto>();
            var groups = types.Select(x => x.RootName).Distinct();


            int i = 1000;
            int j = 500;
            foreach (var item in groups)
            {
                i++;
                var root = new GetDocumentCheckedTreeDto();
                if (!string.IsNullOrEmpty(item))
                {
                    root.id = i.ToString();
                    root.children = new List<GetDocumentCheckedTreeDto>();
                    root.expanded = false;
                    root.@checked = false;
                    root.leaf = false;
                    root.parentId = "0";
                    root.text = item;
                    result.Add(root);
                }

                var parents = types.Where(x => x.RootName == item).Select(x => x.ParentName).Distinct();

                foreach (var p in parents)
                {
                    j++;
                    var parent = new GetDocumentCheckedTreeDto();
                    if (!string.IsNullOrEmpty(p))
                    {
                        parent.id = j.ToString();
                        parent.children = new List<GetDocumentCheckedTreeDto>();
                        parent.expanded = false;
                        parent.leaf = false;
                        parent.@checked = false;
                        parent.parentId = "0";
                        parent.text = p;
                        if (!string.IsNullOrEmpty(item))
                        {
                            parent.parentId = root.id;
                            root.children.Add(parent);
                        }
                        else
                        {
                            result.Add(parent);
                        }
                    }

                    var childs = types.Where(x => x.ParentName == p);
                    foreach (var c in childs)
                    {
                        if (!string.IsNullOrEmpty(c.Name))
                        {
                            var child = new GetDocumentCheckedTreeDto()
                            {
                                id = c.Id.ToString(),
                                children = null,
                                expanded = true,
                                leaf = true,
                                @checked = pdocs.Contains(c.Id) ? true : false,
                                parentId = "0",
                                text = c.Name
                            };
                            if (!string.IsNullOrEmpty(p))
                            {
                                child.parentId = parent.id;
                                parent.children.Add(child);
                            }
                            else
                            {
                                result.Add(child);
                            }
                        }
                    }
                }
            }
            //var json = result.Where(x => x.parentId == "0").ToList();

            return result.Where(x => x.parentId == "0").ToList();
        }

        public async Task SetProjectDocumentType(SetProjectDocumentTypeInPut input)
        {
            var projectId = int.Parse(input.ProjectId);
            await projectManager.projectDocTypeRepository.DeleteAsync(x => x.ProjectId == projectId);

            foreach (var item in input.Types)
            {
                projectManager.projectDocTypeRepository.Insert(new ProjectDocType()
                {
                    ProjectId = projectId,
                    DocTypeId = int.Parse(item)
                });
            }

            await operationLogManager.Create(projectId, "项目文档上传类型设置", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(input));
        }


        public List<GetDocumentTreeDto> GetProjectDocumentTree(int projectId)
        {
            var docs = projectManager.projectDocTypeRepository.GetAll().Where(x => x.ProjectId == projectId).Select(x => x.DocTypeId).ToList();
            var types = documentTypeRepository.GetAll().Where(x => docs.Contains(x.Id)).ToList();

            List<GetDocumentTreeDto> result = new List<GetDocumentTreeDto>();
            var groups = types.Select(x => x.RootName).Distinct();


            int i = 1000;
            int j = 500;
            foreach (var item in groups)
            {
                i++;
                var root = new GetDocumentTreeDto();
                if (!string.IsNullOrEmpty(item))
                {
                    root.id = i.ToString();
                    root.children = new List<GetDocumentTreeDto>();
                    root.expanded = false;
                    root.leaf = false;
                    root.parentId = "0";
                    root.text = item;
                    result.Add(root);
                }

                var parents = types.Where(x => x.RootName == item).Select(x => x.ParentName).Distinct();

                foreach (var p in parents)
                {
                    j++;
                    var parent = new GetDocumentTreeDto();
                    if (!string.IsNullOrEmpty(p))
                    {
                        parent.id = j.ToString();
                        parent.children = new List<GetDocumentTreeDto>();
                        parent.expanded = false;
                        parent.leaf = false;
                        parent.parentId = "0";
                        parent.text = p;
                        if (!string.IsNullOrEmpty(item))
                        {
                            parent.parentId = root.id;
                            root.children.Add(parent);
                        }
                        else
                        {
                            result.Add(parent);
                        }
                    }

                    var childs = types.Where(x => x.ParentName == p);
                    foreach (var c in childs)
                    {
                        if (!string.IsNullOrEmpty(c.Name))
                        {
                            var child = new GetDocumentTreeDto()
                            {
                                id = c.Id.ToString(),
                                children = null,
                                expanded = true,
                                leaf = true,
                                parentId = "0",
                                text = c.Name
                            };
                            if (!string.IsNullOrEmpty(p))
                            {
                                child.parentId = parent.id;
                                parent.children.Add(child);
                            }
                            else
                            {
                                result.Add(child);
                            }
                        }
                    }
                }
            }
            //var json = result.Where(x => x.parentId == "0").ToList();

            return result.Where(x => x.parentId == "0").ToList();
        }


        public List<GetDocumentOutPut> GetDocument(int typeId, int projectId)
        {
            var result = projectManager.projectDocmeutRepository.GetAll().Where(x => x.DocTypeId == typeId && x.ProjectId == projectId).ToList();
            var model = result.MapTo<List<GetDocumentOutPut>>();
            return model;
        }


        public async Task UploadDocument()
        {
            var typeId = HttpContext.Current.Request.Form["TypeId"];
            var projectId = HttpContext.Current.Request.Form["ProjectId"];
            var file = HttpContext.Current.Request.Files[0];


            int id = projectManager.projectDocmeutRepository.InsertAndGetId(new ProjectDocmeut()
            {
                CommitDate = DateTime.Now,
                Extension = Path.GetExtension(file.FileName),
                DocTypeId = int.Parse(typeId),
                FullUrl = Guid.NewGuid(),
                Length = file.ContentLength / 1024,
                Name = Path.GetFileName(file.FileName),
                ProjectId = int.Parse(projectId),
                VersionNo = 1,
                CreationUser = "debug",
                Versions = new List<ProjectDocmeutVersion>()
            });

            projectManager.projectDocmeutVersionRepository.Insert(new ProjectDocmeutVersion()
            {
                Version = 1,
                CreationUser = "debug",
                Length = file.ContentLength / 1024,
                Content = "",
                Name = Path.GetFileName(file.FileName),
                Extension = Path.GetExtension(file.FileName),
                FullUrl = Guid.NewGuid(),
                OriginalName = file.FileName,
                ProjectDocmeutId = id
            });
            await operationLogManager.Create(int.Parse(projectId), "项目文档上传", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectId = projectId, TypeId = typeId }));
        }


        public List<GetDocumentVersionOutPut> GetDocumentVersion(int documentId)
        {
            var result = projectManager.projectDocmeutVersionRepository.GetAll().OrderByDescending(x => x.Version).Where(x => x.ProjectDocmeutId == documentId).ToList();
            var model = result.MapTo<List<GetDocumentVersionOutPut>>();
            return model;
        }


        public async Task EditDocument()
        {
            var documentId = HttpContext.Current.Request.Form["DocumentId"];
            var file = HttpContext.Current.Request.Files[0];

            var doc = await projectManager.projectDocmeutRepository.GetAsync(int.Parse(documentId));
            var newVersion = doc.VersionNo + 1;

            doc.Name = Path.GetFileName(file.FileName);
            doc.Extension = Path.GetExtension(file.FileName);
            doc.Length = file.ContentLength / 1024;
            doc.VersionNo = newVersion;


            projectManager.projectDocmeutVersionRepository.Insert(new ProjectDocmeutVersion()
            {
                Version = newVersion,
                CreationUser = "debug",
                Length = file.ContentLength / 1024,
                Content = "",
                Name = Path.GetFileName(file.FileName),
                Extension = Path.GetExtension(file.FileName),
                FullUrl = Guid.NewGuid(),
                OriginalName = file.FileName,
                ProjectDocmeutId = doc.Id
            });
            await operationLogManager.Create(doc.ProjectId, "项目文档编辑", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectId = doc.ProjectId, DocumentId = documentId }));
        }


        public async Task RemoveDocument(int documentId, int projectId)
        {
            await projectManager.projectDocmeutRepository.DeleteAsync(documentId);
            await operationLogManager.Create(projectId, "项目文档移除", HostOperation.项目, Newtonsoft.Json.JsonConvert.SerializeObject(new { ProjectId = projectId, DocumentId = documentId }));
        }
    }
}
